package org.tio.webpack.app;

import java.io.File;
import java.io.IOException;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tio.utils.freemarker.FreemarkerUtils;
import org.tio.utils.json.Json;
import org.tio.webpack.compress.ResCompressor;
import org.tio.webpack.compress.ResCompressorFactory;
import org.tio.webpack.init.PropInit;
import org.tio.webpack.model.Root;

import com.jfinal.kit.PropKit;
import com.xiaoleilu.hutool.util.ArrayUtil;

import freemarker.template.Configuration;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import jodd.io.FileNameUtil;
import jodd.io.FileUtil;

/**
 * @author tanyaowu 
 * 2017年11月13日 下午3:33:54
 */
public class TioWebpackBuildStarter {
	private static Logger log = LoggerFactory.getLogger(TioWebpackBuildStarter.class);

	/**
	 * 
	 * @author tanyaowu
	 */
	public TioWebpackBuildStarter() {
	}

	static Root model = null;
	
	static Map maoModel = null;
	
	static String[] suffixes;
	
	static String charset = null;

	/**
	 * @param args
	 * @author tanyaowu
	 * @throws IOException 
	 */
	public static void main(String[] args) throws Exception {

		//		System.getProperty("src");
		//		System.getProperty("target");

		try {
			PropInit.init();
			
			suffixes = StringUtils.split(PropKit.get("freemarker.suffix", ""), "|");
			
			charset = PropKit.get("file.charset", "utf-8");
			

			model = null;
			String modelFilePath;
			if (args != null && args.length > 0) {
				modelFilePath = args[0];
			} else {
				modelFilePath = "dist.json";
			}
			
			String modelAbsFile = com.xiaoleilu.hutool.io.FileUtil.getAbsolutePath("classpath:" + modelFilePath);
			File modelFile = new File(modelAbsFile);
			log.info("modelAbsFile:{}", modelAbsFile);
			String content = com.xiaoleilu.hutool.io.FileUtil.readString(modelFile, charset);
			model = Json.toBean(content, Root.class);
			
			maoModel = Json.toBean(content, Map.class);

			String src = PropKit.get("http.page");

			String target = PropKit.get("build.to");

			File srcDir = new File(src);
			if (!srcDir.exists()) {
				log.error("源目录{}不存在", srcDir.getCanonicalPath());
				System.exit(1);
			}

			File targetDir = new File(target);
			if (!targetDir.exists()) {
				targetDir.mkdirs();
			}

			FileUtil.copy(targetDir.getCanonicalPath(), targetDir.getCanonicalPath() + "_back");

			FileUtil.cleanDir(targetDir);

			Configuration cfg = new Configuration(Configuration.getVersion());

			// Specify the source where the template files come from. Here I set a
			// plain directory for it, but non-file-system sources are possible too:
			cfg.setDirectoryForTemplateLoading(srcDir);

			// Set the preferred charset template files are stored in. UTF-8 is
			// a good choice in most applications:
			cfg.setDefaultEncoding(charset);

			// Sets how errors will appear.
			// During web page *development* TemplateExceptionHandler.HTML_DEBUG_HANDLER is better.
			cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);

			// Don't log exceptions inside FreeMarker that it will thrown at you anyway:
			cfg.setLogTemplateExceptions(true);

			// Wrap unchecked exceptions thrown during template processing into TemplateException-s.
			cfg.setWrapUncheckedExceptions(true);

			recursionFile(srcDir, targetDir, srcDir, cfg);
		} catch (Throwable e) {
			log.error(e.toString(), e);
			System.exit(1);
		}
	}

	private static void recursionFile(File srcRoot, File targetRoot, File currDir, Configuration cfg) throws IOException, TemplateException {
		if (currDir.exists()) {
			File[] files = currDir.listFiles();
			if (files.length == 0) {
				log.info("文件夹是空的!");
				return;
			} else {
				for (File currFile : files) {
					if (currFile.isDirectory()) {
						log.info("文件夹:" + currFile.getCanonicalPath());
						recursionFile(srcRoot, targetRoot, currFile, cfg);
					} else {
						log.info("文件:" + currFile.getCanonicalPath());
						String templateFilePath = currFile.getCanonicalPath().substring(srcRoot.getCanonicalPath().length());
						
						String currFilePath = currFile.getCanonicalPath();
						
						String extension = FileNameUtil.getExtension(currFilePath);
						
						byte[] bytes = null;
						String content = null;
						if (ArrayUtil.contains(suffixes, extension)) {
							try {
								content = FreemarkerUtils.generateStringByFile(templateFilePath, cfg, maoModel);
								bytes = content.getBytes(charset);
							} catch (Throwable e) {
								bytes = FileUtil.readBytes(currFile.getCanonicalPath());
							}
						} else {
							bytes = FileUtil.readBytes(currFile.getCanonicalPath());
						}
						

						if (StringUtils.isNotBlank(content)) {
							if (ResCompressorFactory.isNeedCompress(TioWebpackBuildStarter.model, extension)) {
								ResCompressor resCompressor = ResCompressorFactory.get(extension);
								if (resCompressor != null) {
									content = resCompressor.compress(currFilePath, content);
									bytes = content.getBytes(charset);
								}
							}
						}
						
						File destFile = new File(targetRoot, templateFilePath);
						if (!destFile.exists()) {
							File destDir = destFile.getParentFile();
							if (!destDir.exists()) {
								destDir.mkdirs();
							}
							destFile.createNewFile();
						}
						
						FileUtil.writeBytes(destFile, bytes);
					}
				}
			}
		} else {
			log.info("文件不存在!");
		}
	}

	public static void generate(Configuration cfg) {

	}
}
